package com.github.manx98.okdownloader.utils;

import com.github.manx98.okdownloader.common.DownloadErrorLevel;
import okhttp3.Call;

import java.util.Objects;

/**
 * 下载任务块信息
 *
 * @author : manx98
 * @date : 2021/5/26
 */
public class DownloadBlockInfo {
    protected final Object startLock = new Object();
    protected final Object endLock = new Object();
    protected volatile long start;
    protected volatile long end;
    protected volatile long seek;
    protected volatile short code;
    protected Call call;

    /**
     * 任务块
     *
     * @param start 开始下标
     * @param end   结束位置
     * @param seek  进度存储偏移(每个下载块必须保证不同)
     */
    protected DownloadBlockInfo(long start, long end, long seek) {
        this.start = start;
        this.end = end;
        this.seek = seek;
        this.code = DownloadErrorLevel.RUNNING;
    }

    /**
     * 获取起始下标
     *
     * @return 起始下标
     */
    public long getStart() {
        synchronized (startLock) {
            return start;
        }
    }

    /**
     * 修改下载起始
     *
     * @param start 起始下标
     */
    protected void setStart(long start) {
        synchronized (startLock) {
            this.start = start;
        }
    }

    /**
     * 获取结束下标
     *
     * @return 结束下标
     */
    public long getEnd() {
        synchronized (endLock) {
            return end;
        }
    }

    /**
     * 修改结束下标
     *
     * @param end 结束下标
     */
    protected void setEnd(long end) {
        synchronized (endLock) {
            this.end = end;
        }
    }

    /**
     * 获取数据存储下标
     */
    public long getSeek() {
        return seek;
    }

    /**
     * 修改数据存储下标
     */
    protected void setSeek(long seek) {
        this.seek = seek;
    }

    /**
     * 获取状态码
     *
     * @return 状态码
     */
    public short getCode() {
        return code;
    }

    /**
     * 设置状态码
     *
     * @param code 状态码
     */
    protected void setCode(short code) {
        this.code = code;
    }

    /**
     * 更新起点
     *
     * @param length 数据长度
     */
    protected void complete(int length) {
        synchronized (startLock) {
            start += length;
        }
    }

    @Override
    public String toString() {
        return "DownloadBlockProgressInfo{" +
                "start=" + start +
                ", end=" + end +
                ", seek=" + seek +
                ", code=" + code +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        DownloadBlockInfo that = (DownloadBlockInfo) o;
        return getSeek() == that.getSeek();
    }

    @Override
    public int hashCode() {
        return Objects.hash(getSeek());
    }

    protected synchronized Call getCall() {
        return call;
    }

    protected synchronized void setCall(Call call) {
        this.call = call;
    }
}
